package org.example;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;

import javax.swing.*;
import java.awt.*;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.time.LocalDate;
import java.time.YearMonth;
import java.util.HashMap;
import java.util.Map;

public class FixedHeaderCalendarTest {
    private JFrame frame;
    private LocalDate currentDate;
    private LocalDate realCurrentDate;
    private int clickCount = 0; // 记录连续点击次数
    private boolean isDarkMode = false; // 记录当前主题状态
    private Color MicrosoftWhite = new Color(242, 242, 242);
    private Color MicrosoftBlack = new Color(34, 34, 34);
    private static Map<String, String> notesMap = new HashMap<>();;  // 用于存储每个日期的备注
    private static final String NOTES_FILE = "notes.json"; // 存储文件路径
    private static final ObjectMapper objectMapper = new ObjectMapper();
    public FixedHeaderCalendarTest() {
        currentDate = LocalDate.now();
        realCurrentDate = LocalDate.now();
        loadNotes();  // 加载之前保存的备注
        createAndShowGUI();
    }

    private void createAndShowGUI() {
        // 创建主窗口
        frame = new JFrame();

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setUndecorated(false); // 去除边框
        frame.setResizable(true);
        frame.setAlwaysOnTop(false); // 窗口置顶

        // 创建内容面板
        JPanel panel = new JPanel();
        panel.setLayout(new BorderLayout());

        // 添加标题栏和日历
        panel.add(createHeader(), BorderLayout.NORTH);
        panel.add(createCalendarPanel(), BorderLayout.CENTER);

        // 设置窗口属性
        frame.setTitle("阳历"); // 设置窗口标题
        frame.setContentPane(panel);
        frame.setSize(1200, 1300);
        frame.setLocationRelativeTo(null); // 居中显示
        frame.setIconImage(new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB)); // 设置一个1x1的透明icon标题图片
        frame.setVisible(true);

    }

    private JPanel createHeader() {
        JPanel headerPanel = new JPanel(new BorderLayout());
        headerPanel.setOpaque(true);
        headerPanel.setBackground(MicrosoftWhite); // 背景色

        headerPanel.setPreferredSize(new Dimension(400, 50)); // 设置固定高度

        JButton prevButton = new JButton("<");
        stylePureColorButton(prevButton, MicrosoftWhite); // 设置按钮为浅蓝色
        prevButton.addActionListener(e -> changeMonth(-1));

        JButton nextButton = new JButton(">");
        stylePureColorButton(nextButton, MicrosoftWhite); // 设置按钮为浅蓝色
        nextButton.addActionListener(e -> changeMonth(1));

        JLabel monthLabel = new JLabel("  "+currentDate.getYear() + "年" + currentDate.getMonthValue() + "月", SwingConstants.CENTER);
        monthLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 28));
        monthLabel.setForeground(Color.BLACK);
        // 右键菜单
        JPopupMenu headerMenu = new JPopupMenu();

        // 导出菜单项
        JMenuItem exportItem = new JMenuItem("导出");
        exportItem.setFont(new Font("宋体", Font.PLAIN, 24));
        exportItem.addActionListener(e -> exportNotesToJson());
        headerMenu.add(exportItem);

        // 添加鼠标监听器，连续点击 3 次切换主题
        monthLabel.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                clickCount++;
                if (clickCount == 3) {
                    toggleDarkMode(); // 切换主题
                    clickCount = 0;   // 重置点击次数
                }
            }
            @Override
            public void mousePressed(MouseEvent e) {
                if (SwingUtilities.isRightMouseButton(e)) {
                    headerMenu.show(e.getComponent(), e.getX(), e.getY());
                }
            }
        });

        headerPanel.add(prevButton, BorderLayout.WEST);
        headerPanel.add(monthLabel, BorderLayout.CENTER);
        headerPanel.add(nextButton, BorderLayout.EAST);

        return headerPanel;
    }

    private void toggleDarkMode() {
        isDarkMode = !isDarkMode; // 切换主题状态

        // 设置主窗口背景颜色
        frame.getContentPane().setBackground(isDarkMode ? MicrosoftBlack : MicrosoftWhite);

        // 递归更新所有组件的颜色
        updateComponentTheme(frame.getContentPane());
    }

    private void updateComponentTheme(Container container) {
        frame.setTitle(isDarkMode ? "阴历" : "阳历");

        for (Component component : container.getComponents()) {
            if (component instanceof JPanel) {
                component.setBackground(isDarkMode ? MicrosoftBlack : MicrosoftWhite);
            } else if (component instanceof JLabel) {
                component.setForeground(isDarkMode ? Color.WHITE : Color.BLACK);
            } else if (component instanceof JButton) {
                component.setBackground(isDarkMode ? new Color(64, 64, 64) : MicrosoftWhite);
                component.setForeground(isDarkMode ? Color.WHITE : Color.BLACK);
            } else if (component instanceof JTextArea) {
                component.setBackground(isDarkMode ? new Color(48, 48, 48) : MicrosoftWhite);
                component.setForeground(isDarkMode ? Color.WHITE : Color.BLACK);
            }

            // 递归更新子组件
            if (component instanceof Container) {
                updateComponentTheme((Container) component);
            }
        }
    }

    private JPanel createCalendarPanel() {
        // 日历面板，包含星期和日期
        JPanel calendarPanel = new JPanel();
        calendarPanel.setLayout(new BorderLayout());

        // 添加星期行（固定在顶部）
        JPanel dayPanel = new JPanel(new GridLayout(1, 7));  // 一行7列，显示星期
        dayPanel.setBackground(new Color(242, 242, 242)); // 微软风格的浅灰色
        String[] dayNames = {"一", "二", "三", "四", "五", "六", "日"};
        Font font = new Font("Microsoft YaHei", Font.BOLD, 24); // 使用支持中文的字体
        Font fontTxt = new Font("宋体", Font.BOLD, 20); // 使用支持中文的字体

        for (String dayName : dayNames) {
            JLabel dayLabel = new JLabel(dayName, SwingConstants.CENTER);
            dayLabel.setFont(font);
            dayLabel.setForeground(Color.BLACK);
            dayPanel.add(dayLabel);
        }
        dayPanel.setPreferredSize(new Dimension(400, 50)); // 设置固定高度

        // 添加日期区域
        JPanel datePanel = new JPanel(new GridLayout(0, 7));  // 根据日期填充
        datePanel.setBackground(new Color(242, 242, 242)); // 完全透明

        datePanel.setPreferredSize(new Dimension(400, 400));

        // 获取当前月份信息
        YearMonth yearMonth = YearMonth.of(currentDate.getYear(), currentDate.getMonthValue());
        int daysInMonth = yearMonth.lengthOfMonth();
        int realMonthValue = realCurrentDate.getMonthValue();
        // 获取当前月第一天是星期几，Java中返回1（周一）到7（周日）
        int firstDayOfWeek = LocalDate.of(currentDate.getYear(), currentDate.getMonthValue(), 1)
                .getDayOfWeek()
                .getValue(); // 1=周一, ..., 7=周日

        // 填充空白，确保日期对齐
        for (int i = 0; i < firstDayOfWeek - 1; i++) {
            datePanel.add(new JLabel());  // 填充空白
        }

        // 填充日期文本框
        for (int day = 1; day <= daysInMonth; day++) {
            JTextArea dateArea = new JTextArea();
            dateArea.setFont(fontTxt);
            dateArea.setLineWrap(true);       // 自动换行
            dateArea.setWrapStyleWord(true); // 单词边界换行
            dateArea.setOpaque(false);       // 背景透明
            dateArea.setForeground(Color.black);
            dateArea.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); // 设置边距

            // 设置文本内容（加载之前的备注）
            String dateKey = currentDate.getYear() + "-" + currentDate.getMonthValue() + "-" + day;
            dateArea.setText(notesMap.getOrDefault(dateKey, ""));
            // 添加鼠标事件监听器
            dateArea.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseEntered(MouseEvent e) {
                    dateArea.setBorder(BorderFactory.createLineBorder(Color.GRAY)); // 鼠标移入时显示边框
                }

                @Override
                public void mouseExited(MouseEvent e) {
                    dateArea.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); // 鼠标移出时移除边框
                    saveNote(dateArea.getText(), dateKey);
                }
            });
            // 添加焦点丢失时保存功能
            dateArea.addFocusListener(new FocusAdapter() {
                @Override
                public void focusLost(FocusEvent e) {
                    saveNote(dateArea.getText(), dateKey);
                }
            });
            // 使用 JScrollPane 包裹 JTextArea
            JScrollPane jScrollPane = new JScrollPane(dateArea);
            jScrollPane.setBorder(null); // 去掉 JScrollPane 的边框
            jScrollPane.setViewportBorder(null); // 清除视口边框（可选）
            jScrollPane.getViewport().setOpaque(false); // 让视口透明
            jScrollPane.setOpaque(false); // JScrollPane 自身透明
            jScrollPane.setBorder(null); // 移除边框
            jScrollPane.getVerticalScrollBar().setPreferredSize(new Dimension(0, 0)); // 隐藏垂直滚动条
            jScrollPane.getHorizontalScrollBar().setPreferredSize(new Dimension(0, 0)); // 隐藏水平滚动条


            // 创建一个面板来容纳日期标签和文本框
            JPanel dayPanelWithLabel = new JPanel(new BorderLayout());
            dayPanelWithLabel.setOpaque(false);

            // 日期标签（左上角）
            JLabel dateLabel = new JLabel(String.valueOf(day), SwingConstants.CENTER);
            dateLabel.setFont(font);
            dateLabel.setForeground(Color.BLACK);

            // 如果是今天，设置椭圆背景
            if (currentDate.getMonthValue() == realMonthValue && currentDate.getDayOfMonth() == day) {
                dateLabel.setOpaque(true); // 背景需要透明
                dateLabel.setBackground(new Color(70, 130, 180)); // 椭圆蓝色
                dateLabel.setBorder(BorderFactory.createLineBorder(Color.WHITE, 1)); // 边框为白色
                dateLabel.setForeground(Color.WHITE); // 字体颜色为白色
            }

            // 将日期标签和文本框添加到面板
            dayPanelWithLabel.add(dateLabel, BorderLayout.NORTH);
            dayPanelWithLabel.add(jScrollPane, BorderLayout.CENTER);

            datePanel.add(dayPanelWithLabel);
        }


        // 填充剩余空白格
        int totalCells = firstDayOfWeek + daysInMonth - 1;
        int remainingCells = 7 - (totalCells % 7);
        if (remainingCells < 7) {
            for (int i = 0; i < remainingCells; i++) {
                datePanel.add(new JLabel());  // 填充剩余空白格
            }
        }

        // 将星期行和日期面板添加到日历面板
        JScrollPane scrollPane = new JScrollPane(datePanel);
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER); // 隐藏垂直滚动条
        scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); // 隐藏水平滚动条

        // 日历面板添加星期行和日期区域、导出按钮
        calendarPanel.add(dayPanel, BorderLayout.NORTH);
        calendarPanel.add(scrollPane, BorderLayout.CENTER);
        frame.setVisible(true);
        return calendarPanel;
    }
    // 设置纯色按钮样式的辅助方法
    private void stylePureColorButton(JButton button, Color color) {
        button.setBackground(color); // 设置背景颜色
        button.setForeground(Color.BLACK); // 设置字体颜色
        button.setFocusPainted(false); // 去除焦点效果
        button.setBorderPainted(false); // 去除边框
        button.setContentAreaFilled(true); // 确保内容区域填充背景色
        button.setOpaque(true); // 确保背景颜色可见
        button.setFont(new Font("Microsoft YaHei", Font.BOLD, 18)); // 设置字体样式
    }

    private void saveNote(String note, String dateKey) {
        notesMap.put(dateKey, note);
        saveNotes();  // 保存到本地
    }

    // 加载保存的备注
    private void loadNotes() {
        File file = new File(NOTES_FILE);
        if (file.exists()) {
            try {
                notesMap = objectMapper.readValue(file, HashMap.class);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    // 将备注保存到本地文件
    private void saveNotes() {
        try {
            objectMapper.writerWithDefaultPrettyPrinter().writeValue(new File(NOTES_FILE), notesMap);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void changeMonth(int offset) {
        currentDate = currentDate.plusMonths(offset);
        frame.dispose();
        createAndShowGUI();
        // 递归更新所有组件的颜色
        if (isDarkMode){
            updateComponentTheme(frame.getContentPane());
        }
    }
    private static void exportNotesToJson() {
        // 使用 JFileChooser 弹出文件选择窗口
        JFileChooser fileChooser = new JFileChooser();
        fileChooser.setDialogTitle("选择导出位置");
        fileChooser.setSelectedFile(new File("calendar_notes.json")); // 默认文件名

        // 只允许保存为文件
        int userSelection = fileChooser.showSaveDialog(null);

        if (userSelection == JFileChooser.APPROVE_OPTION) {
            File fileToSave = fileChooser.getSelectedFile();
            try (FileWriter writer = new FileWriter(fileToSave)) {
                Gson gson = new Gson();
                String json = gson.toJson(notesMap); // 将日期备注转换为 JSON 格式
                writer.write(json);
                JOptionPane.showMessageDialog(null, "导出成功！", "导出", JOptionPane.INFORMATION_MESSAGE);
            } catch (IOException e) {
                JOptionPane.showMessageDialog(null, "导出失败！", "错误", JOptionPane.ERROR_MESSAGE);
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(FixedHeaderCalendarTest::new);
    }
}
